﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YJKArchBaseCode.OutWallSearch;

namespace YJKInspectModel.PerformanceAnalysis.AreaRatioWindowToWall
{
	internal class AreaRatioStructMaker
	{
		public Document Doc
		{
			get
			{
				return this.m_Doc;
			}
		}

		public FacadeMaker FacadeMaker
		{
			get
			{
				return this.m_FacadeMaker;
			}
		}

		public List<AreaRatioStruct> AllAreaRatioStructList
		{
			get
			{
				return this.m_AllAreaRatioStructList;
			}
		}

		public List<AreaRatioStruct> NorthAreaRatioStructList
		{
			get
			{
				return this.m_NorthAreaRatioStructList;
			}
		}

		public List<AreaRatioStruct> SouthAreaRatioStructList
		{
			get
			{
				return this.m_SouthAreaRatioStructList;
			}
		}

		public List<AreaRatioStruct> WestAreaRatioStructList
		{
			get
			{
				return this.m_WestAreaRatioStructList;
			}
		}

		public List<AreaRatioStruct> EastAreaRatioStructList
		{
			get
			{
				return this.m_EastAreaRatioStructList;
			}
		}

		public ViewPlan ViewPlan
		{
			get
			{
				return this.m_viewPlan;
			}
		}

		internal AreaRatioStructMaker(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, FacadeMaker facadeMaker)
		{
			this.m_Doc = doc;
			this.m_FacadeMaker = facadeMaker;
			this.m_viewPlan = viewPlan;
			this.m_NorthAreaRatioStructList = new List<AreaRatioStruct>();
			this.m_SouthAreaRatioStructList = new List<AreaRatioStruct>();
			this.m_WestAreaRatioStructList = new List<AreaRatioStruct>();
			this.m_EastAreaRatioStructList = new List<AreaRatioStruct>();
			this.m_AllAreaRatioStructList = new List<AreaRatioStruct>();
		}

		public bool GetAllAreaRatioStruct()
		{
			List<Wall> allExteriorWall = this.GetAllExteriorWall();
			if (allExteriorWall.Count <= 0)
			{
				return false;
			}
			foreach (Wall wall in allExteriorWall)
			{
				AreaRatioStruct item = new AreaRatioStruct();
				if (this.CreateAreaRatioStructByWall(wall, ref item))
				{
					this.m_AllAreaRatioStructList.Add(item);
				}
			}
			return true;
		}

		private List<Wall> GetAllExteriorWall()
		{
			List<Wall> result = new List<Wall>();
			OutWallFilter.Search(this.m_Doc, this.m_viewPlan.Id, ref result, true, true);
			return result;
		}

		private bool CreateAreaRatioStructByWall(Wall wall, ref AreaRatioStruct tempAreaRatioStruct)
		{
			tempAreaRatioStruct.Orientation = wall.Orientation;
			double num = wall.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble();
			double windowAndDoorAreaInHostID = this.GetWindowAndDoorAreaInHostID(wall);
			tempAreaRatioStruct.CaveArea = windowAndDoorAreaInHostID;
			tempAreaRatioStruct.WallArea = num + windowAndDoorAreaInHostID;
			return true;
		}

		private double GetWindowAndDoorAreaInHostID(Wall wall)
		{
			double num = 0.0;
			int integerValue = wall.Id.IntegerValue;
			if (!RelationWindowToWall.DoorAndWindowList.ContainsKey(integerValue))
			{
				return 0.0;
			}
			foreach (FamilyInstance familyInstance in RelationWindowToWall.DoorAndWindowList[integerValue])
			{
				double num2 = familyInstance.Symbol.get_Parameter(BuiltInParameter.CASEWORK_WIDTH).AsDouble();
				double num3 = familyInstance.Symbol.get_Parameter(BuiltInParameter.FAMILY_HEIGHT_PARAM).AsDouble();
				double num4 = num2 * num3;
				num += num4;
			}
			return num;
		}

		public void MakeAreaRatioListInFacade()
		{
			foreach (AreaRatioStruct inputAreaRatioStruct in this.m_AllAreaRatioStructList)
			{
				this.AddAreaRatioToFacadeList(inputAreaRatioStruct);
			}
		}

		private void AddAreaRatioToFacadeList(AreaRatioStruct inputAreaRatioStruct)
		{
			switch (this.GetAreaRatioDirection(inputAreaRatioStruct))
			{
			case FacadeDirection.NorthFacade:
				this.m_NorthAreaRatioStructList.Add(inputAreaRatioStruct);
				return;
			case FacadeDirection.SouthFacade:
				this.m_SouthAreaRatioStructList.Add(inputAreaRatioStruct);
				return;
			case FacadeDirection.WestFacade:
				this.m_WestAreaRatioStructList.Add(inputAreaRatioStruct);
				return;
			case FacadeDirection.EastFacade:
				this.m_EastAreaRatioStructList.Add(inputAreaRatioStruct);
				break;
			case FacadeDirection.Empty:
				break;
			default:
				return;
			}
		}

		private FacadeDirection GetAreaRatioDirection(AreaRatioStruct inputAreaRatioStruct)
		{
			bool flag = this.IfAreaRationInFacade(inputAreaRatioStruct, this.m_FacadeMaker.NorthFacade);
			bool flag2 = this.IfAreaRationInFacade(inputAreaRatioStruct, this.m_FacadeMaker.SouthFacade);
			bool flag3 = this.IfAreaRationInFacade(inputAreaRatioStruct, this.m_FacadeMaker.WestFacade);
			bool flag4 = this.IfAreaRationInFacade(inputAreaRatioStruct, this.m_FacadeMaker.EastFacade);
			if (flag)
			{
				return FacadeDirection.NorthFacade;
			}
			if (flag2)
			{
				return FacadeDirection.SouthFacade;
			}
			if (flag3)
			{
				return FacadeDirection.WestFacade;
			}
			if (flag4)
			{
				return FacadeDirection.EastFacade;
			}
			return FacadeDirection.Empty;
		}

		private bool IfAreaRationInFacade(AreaRatioStruct inputAreaRatioStruct, Facade facade)
		{
			XYZ orientation = inputAreaRatioStruct.Orientation;
			XYZ startVector = facade.StartVector;
			XYZ endVector = facade.EndVector;
			XYZ xyz = new XYZ(startVector.Y * endVector.Z - endVector.Y * startVector.Z, startVector.Z * endVector.X - endVector.Z * startVector.X, startVector.X * endVector.Y - endVector.X * startVector.Y);
			double num = Math.Sqrt(Math.Pow(xyz.X, 2.0) + Math.Pow(xyz.Y, 2.0) + Math.Pow(xyz.Z, 2.0));
			XYZ xyz2 = new XYZ(xyz.X / num, xyz.Y / num, xyz.Z / num);
			double num2 = startVector.AngleOnPlaneTo(endVector, xyz2);
			double num3 = startVector.AngleOnPlaneTo(orientation, xyz2);
			double num4 = num3 % Math.PI*2;
			return (num3 + this.m_Tolerance < num2 && num3 >= -this.m_Tolerance) || Math.Abs((this.m_Tolerance + num3) % Math.PI*2) < this.m_Tolerance;
		}

		private double m_Tolerance = 0.1;

		private Document m_Doc;

		private FacadeMaker m_FacadeMaker;

		private List<AreaRatioStruct> m_AllAreaRatioStructList;

		private List<AreaRatioStruct> m_NorthAreaRatioStructList;

		private List<AreaRatioStruct> m_SouthAreaRatioStructList;

		private List<AreaRatioStruct> m_WestAreaRatioStructList;

		private List<AreaRatioStruct> m_EastAreaRatioStructList;

		private ViewPlan m_viewPlan;
	}
}
